﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls.Base;
using Silvermoon.Controls.Forms;
using Silvermoon.Shapes;
using Silvermoon.UI;
using System.Drawing;
using Silvermoon.Windows;
using Silvermoon.OpenGL;

namespace Silvermoon.Controls
{
    #region enums

    /// <summary>
    /// Specifies what event is causing the ContextMenu to appear.
    /// </summary>
    public enum AppearBehavior
    {
        /// <summary>
        /// context menu appears on Hold.
        /// </summary>
        OnHold,

        /// <summary>
        /// context menu appears on TouchDown.
        /// </summary>
        OnTouchDown
    }

    #endregion

    public abstract class ContextMenuBase : ToolTipBase
    {
        private static readonly Dictionary<int, ContextMenuBase> attachedContextMenus = new Dictionary<int, ContextMenuBase>();
        private static ContextMenuBase openedMenu;
        private AppearBehavior appearBehavior;

        public AppearBehavior Behavior
        {
            get { return appearBehavior; }
            set { appearBehavior = value; }
        }

        public static ContextMenuBase GetContextMenu(Control control)
        {
            if (control == null) throw new ArgumentNullException("control");
            int key = control.GetHashCode();
            ContextMenuBase contextMenu;
            if (attachedContextMenus.TryGetValue(key, out contextMenu))
            {
                return contextMenu;
            }
            return null;
        }

        public virtual void AddControl(Control anchor)
        {
            if (anchor == null) throw new ArgumentNullException("anchor");
            int key = anchor.GetHashCode();

            Control parent = ContextMenuBase.GetContextMenu(anchor);
            if (parent != null) RemoveControl(parent);

            anchor.IsHoldEnabled = true;
            anchor.ControlFlags |= ControlFlags.ContextMenu;
            attachedContextMenus[key] = this;

        }

        public virtual void RemoveControl(Control anchor)
        {
            if (anchor == null) throw new ArgumentNullException("anchor");
            anchor.ControlFlags &= ~ControlFlags.ContextMenu;
            int key = anchor.GetHashCode();
            attachedContextMenus.Remove(key);
        }

        public static ContextMenuBase OpenedMenu
        {
            get { return openedMenu; }
            private set { openedMenu = value; }
        }

        public virtual void Open(Control anchorControl)
        {
            AnchorBounds = anchorControl.GetToolTipAnchor();
            if (!IsInitialized) ApplyStyle();
            if (OpenedMenu != null && OpenedMenu != this) OpenedMenu.Hide();
            OpenedMenu = this;
            AnchorControl = anchorControl;
            if (Opening != null) Opening(this, EventArgs.Empty);
            OnShowContextMenu(anchorControl, EventArgs.Empty);
            Show();
        }

        public virtual void OnCancelOpening(object sender, TouchEventArgs e)
        {
            e.Handled = true;
            if (!e.IsTouched && Visibility < 1f) Hide();
        }

        protected override void OnHidden()
        {
            OpenedMenu = null;
            base.OnHidden();
        }


        #region events

        public event EventHandler Opening;

        #endregion
    }

}
